/*****************************************************************
Mix3D WebGL Game Engine
Copyright (c) fantasy ( fantasy.x2x@gmail.com )
Listens:
Distributed under the Boost Software License, Version 1.0.
http://www.boost.org/LICENSE_1_0.txt
 ****************************************************************/
/**
 * @Desc    : face( triangle/quad)
 * @Author  : fantasy(fantasy.x2x@gmail.com)
 */
//////////////////////////////////////////////////////////////////
if(typeof(Mix3D) === 'undefined')
{
  Mix3D = {};
};
(function(Mix3D){
//////////////////////////////////////////////////////////////////
//
//    Triangle or quad Face
//
//////////////////////////////////////////////////////////////////
Mix3D.Face = function( a, b, c, d, normal, color, materialIndex )
{
  this.a = a;
  this.b = b;
  this.c = c;
  this.d = d;
  this.fas = {};
  if(normal !== undefined)this.setFaceVec3('normal', normal);
  if(color !== undefined)this.setFaceVec3('color', color );
  this.matIdx = materialIndex!==undefined?materialIndex:-1;
  this.centroid = new Mix3D.Vector3();
};

Mix3D.Face.prototype.constructor = Mix3D.Face;

Mix3D.Face.prototype.getAttrValue = function( name )
{
  return this.fas[name];
};

Mix3D.Face.prototype.setFaceAttrib = function( name, vtxType, array )
{
  var va = this.fas[name];
  if(!va)
  {
    va = new Mix3D.FloatArray(Mix3D.VTA_FloatSize[vtxType]);
    va._vaType = vtxType;
    this.fas[name] = va;
  }
  if(v)
  {
    var dim = Mix3D.Math.Min(va.FA.length, array.length);
    for(var i=0; i<dim; ++i)
    {
      va.FA[i] = array[i];
    }
  }
  return va;
};

Mix3D.Face.prototype.setFaceVec1 = function( name, v )
{
  this.setFaceAttrib(name, Mix3D.VAT_Float1, v.FA);
};

Mix3D.Face.prototype.setFaceVec2 = function( name, v )
{
  this.setFaceAttrib(name, Mix3D.VAT_Float2, v.FA);
};

Mix3D.Face.prototype.setFaceVec3 = function( name, v )
{
  this.setFaceAttrib(name, Mix3D.VAT_Float3, v.FA);
};

Mix3D.Face.prototype.setFaceVec4 = function( name, v )
{
  this.setFaceAttrib(name, Mix3D.VAT_Float4, v.FA);
};

Mix3D.Face.prototype.clone = function()
{
  var face = new Mix3D.Face(this.a, this.b, this.c, this.d);
  for( var item in this.fas )
  {
    face.fas[item] = this.fas[item].clone();
  }
  face.centroid.copy(this.centroid);
  face.matIdx = this.matIdx;
  return face;
};

//////////////////////////////////////////////////////////////////
//
//  Faces
//
//////////////////////////////////////////////////////////////////
Mix3D.Faces = function()
{
  this.faceArray = [];
  this.triangleBuffer = new Mix3D.IndexBuffer(0);
  this.edgeBuffer = new Mix3D.IndexBuffer(0);
  this.indicesByMat = undefined;
  this.facesByMat = undefined;
  this.isDirty = true;
  this.vtxNumByFace = 0;
};

Mix3D.Faces.prototype.constructor = Mix3D.Faces;

Mix3D.Faces.prototype.getFaceNum = function()
{
  return this.faceArray.length;
};

Mix3D.Faces.prototype.getVertexNum = function()
{
  if(!this.vtxNumByFace || this.isDirty)
  {
    var face, num = 0;
    for( var i=0, len = this.faceArray.length; i<len; ++i)
    {
      face = this.faceArray[i];
      if(face.d){num+=4;}
      else{num+=3;}
    }
    this.vtxNumByFace = num;
  }
  return this.vtxNumByFace;
};

Mix3D.Faces.prototype.getFace = function(idx)
{
  return this.faceArray[idx];
};

Mix3D.Faces.prototype.addTri = function(a, b, c, normal, color, matIdx)
{
  var face = new Mix3D.Face(a, b, c, undefined, normal, color, matIdx);
  this.faceArray.push(face);
  this.triangleBuffer.addTri(a, b, c);
  this.edgeBuffer.addTriEdge(a, b, c);
  this.vtxNumByFace +=3;
  return face;
};

Mix3D.Faces.prototype.addQuad = function(a, b, c, d, normal, color, matIdx)
{
  var face = new Mix3D.Face(a, b, c, d, normal, color, matIdx);
  this.faceArray.push(face);
  this.triangleBuffer.addQuad(a, b, c, d);
  this.edgeBuffer.addQuadEdge(a, b, c, d);
  this.vtxNumByFace += 4;
  return face;
};

Mix3D.Faces.prototype.rebuildIndices = function()
{
  var i,len=this.faceArray.length;
  var matIdx;
  this.triangleBuffer.resize(0);
  this.edgeBuffer.resize(0);
  var face;
  var a, b, c, d;
  for( i=0; i<len; ++i)
  {
    face = this.faceArray[i];
    a = face.a; b=face.b; c=face.c;
    if(face.d===undefined)
    {
      this.triangleBuffer.addTri(a, b, c);
      this.edgeBuffer.addTriEdge(a, b, c);
    }
    else
    {
      d = face.d;
      this.triangleBuffer.addQuad(a, b, c, d);
      this.edgeBuffer.addQuadEdge(a, b, c, d);
    }
  }
};

Mix3D.Faces.prototype.getTriangleBuffer = function()
{
  return this.triangleBuffer;
};

/*Mix3D.Faces.prototype.getIdxBufferByMaterial = function( matIdx )
{
  if(matIdx !== undefined)
    return this.indicesByMat[matIdx];
  return this.triangleBuffer;
};*/

Mix3D.Faces.prototype.applyTransform = function(transform)
{
  var i, len, face;
  var mat = transform.getRotMatrix();
	for ( i = 0, len = this.faceArray.length; i < len; ++i ) 
	{
		var face = this.faceArray[ i ];
		for(var item in face.fva )
		{
		  if(face.fva[item].length === 3)
		  {
		    rotMat.mulArray3( face.fva[item] );
		  }
		  rotMat.mulVec3( face.centroid );
		}
	}
};

//////////////////////////////////////////////////////////////////
})(Mix3D);// end of function(Mix3D)